
#include "HalBeep.h"

#if((U8_HAL_MUSIC_BEEP_EN == 1)&&(U8_HAL_BEEP_NUM > 0))

#define     U8_TIM_BASE             (4) ///<单位时间为4ms
///<音乐蜂鸣器低频端输出高电平时间，单位时间ms
#define     BUZ_ON_TIM(tmp)         ((tmp + U8_TIM_BASE/2)/U8_TIM_BASE) 
///<音乐蜂鸣器低频端输出低电平时间，单位时间ms
#define     BUZ_OFF_TIM(tmp)        ((tmp + U8_TIM_BASE/2)/U8_TIM_BASE) 

///<蜂鸣器周期设置，定时器设置：单位时间1us(注意：设置蜂鸣器PWM输出时，需要将单位时间设为1us)
#define     BUZ_CYCLE_SET(tmp)       (tmp)

typedef struct
{   
  uint8 fgBeepEn;
  uint8 fgBeepDisable;
  uint8 u8BuzzerMusicSet;
  uint8 u8SoundType;
  uint8 u8Index;
  uint8 fgBeepFreqStart;
  ST_SOUND_TYPE stSoundBuz;
  void (*BeepPwmStop)(uint8 u8Chn);
  void (*BeepPwmStart)(uint8 u8Chn, uint16 u16BuzFre);
  void (*BeepTimePortSet)(uint8 u8Chn,uint8 u8Tmp);
  void (*BeepFreqPortSet)(uint8 u8Chn,uint8 u8Tmp);
  
}stBeepType;

volatile stBeepType stBeep[U8_HAL_BEEP_NUM];

const ST_SOUND_TYPE u8MusicSoundTab[U8_BUZ_TYPE_SIZE][U8_MAX_BUZZER_TIMES]=	// 曲谱
{
    {{0, 0 , 0}, {0, 0 , 0} , {0, 0 , 0} , {0, 0 , 0} , {0, 0 , 0}},
    ///<上电蜂鸣器声音
    {{BUZ_CYCLE_SET(540), BUZ_ON_TIM(75), BUZ_OFF_TIM(110)}, {BUZ_CYCLE_SET(476), BUZ_ON_TIM(75), BUZ_OFF_TIM(110)}, {BUZ_CYCLE_SET(417), BUZ_ON_TIM(75), BUZ_OFF_TIM(110)}, {BUZ_CYCLE_SET(350), BUZ_ON_TIM(75), BUZ_OFF_TIM(988)}, {0, 0 , 0}},
    ///<开机蜂鸣器声音
    {{BUZ_CYCLE_SET(476), BUZ_ON_TIM(39), BUZ_OFF_TIM(74)}, {BUZ_CYCLE_SET(444), BUZ_ON_TIM(37), BUZ_OFF_TIM(74)}, {BUZ_CYCLE_SET(416), BUZ_ON_TIM(37), BUZ_OFF_TIM(994)}, {0, 0 , 0}, {0, 0 , 0}},
    ///<关机蜂鸣器声音
    {{BUZ_CYCLE_SET(350), BUZ_ON_TIM(38), BUZ_OFF_TIM(75)}, {BUZ_CYCLE_SET(417), BUZ_ON_TIM(37), BUZ_OFF_TIM(74)}, {BUZ_CYCLE_SET(476), BUZ_ON_TIM(37), BUZ_OFF_TIM(985)}, {0, 0 , 0}, {0, 0 , 0}},
    ///<单声蜂鸣器声音
    {{BUZ_CYCLE_SET(416), BUZ_ON_TIM(75), BUZ_OFF_TIM(985)}, {0, 0 , 0}, {0, 0 , 0}, {0, 0 , 0}, {0, 0 , 0}},
    ///<两声蜂鸣器声音
    {{BUZ_CYCLE_SET(416), BUZ_ON_TIM(75), BUZ_OFF_TIM(200)}, {BUZ_CYCLE_SET(416), BUZ_ON_TIM(75), BUZ_OFF_TIM(1000)}, {0, 0 , 0}, {0, 0 , 0}, {0, 0 , 0}},
    ///<短升调
    {{BUZ_CYCLE_SET(606), BUZ_ON_TIM(25), BUZ_OFF_TIM(61)}, {BUZ_CYCLE_SET(540), BUZ_ON_TIM(22), BUZ_OFF_TIM(60)}, {BUZ_CYCLE_SET(476), BUZ_ON_TIM(23), BUZ_OFF_TIM(995)}, {0, 0 , 0}, {0, 0 , 0}},
    ///<短降调
    {{BUZ_CYCLE_SET(476), BUZ_ON_TIM(25), BUZ_OFF_TIM(61)}, {BUZ_CYCLE_SET(540), BUZ_ON_TIM(22), BUZ_OFF_TIM(60)}, {BUZ_CYCLE_SET(607), BUZ_ON_TIM(23), BUZ_OFF_TIM(985)}, {0, 0 , 0}, {0, 0 , 0}},
    ///<长鸣，250us
    {{BUZ_CYCLE_SET(250), BUZ_ON_TIM(700), BUZ_OFF_TIM(1000)}, {0, 0 , 0}, {0, 0 , 0}, {0, 0 , 0}, {0, 0 , 0}},
};


void HalBeepSoundOn(uint8 u8Chn, uint8 u8SoundSel)
{
    if(u8Chn < U8_HAL_BEEP_NUM)
	{
        stBeep[u8Chn].u8Index = 0;
        stBeep[u8Chn].u8SoundType = u8SoundSel;
        stBeep[u8Chn].BeepPwmStop(u8Chn);
        stBeep[u8Chn].BeepFreqPortSet(u8Chn, U8_PIN_LOW);
        stBeep[u8Chn].BeepTimePortSet(u8Chn, U8_PIN_LOW);
    }
}

void HalBeepParaSet(uint8 u8Chn, uint8 u8Index)
{
    uint8 u8Tmp;
    uint16 u16BeepTotalTim;

    if(u8Chn < U8_HAL_BEEP_NUM)
    {
        u8Tmp = stBeep[u8Chn].u8SoundType;
        u16BeepTotalTim = u8MusicSoundTab[u8Tmp][u8Index].u16BuzOnTime + u8MusicSoundTab[u8Tmp][u8Index].u16BuzOffTime;
        if(u16BeepTotalTim != 0)
        {
            stBeep[u8Chn].stSoundBuz.u16BuzOnTime = u8MusicSoundTab[u8Tmp][u8Index].u16BuzOnTime;
            stBeep[u8Chn].stSoundBuz.u16BuzOffTime = u8MusicSoundTab[u8Tmp][u8Index].u16BuzOffTime;
            stBeep[u8Chn].stSoundBuz.u16Freq = u8MusicSoundTab[u8Tmp][u8Index].u16Freq;
            stBeep[u8Chn].fgBeepFreqStart = 0;
            stBeep[u8Chn].fgBeepEn = 1;
        }
        else
        {
            ///<驱动总时间为零，关闭蜂鸣器
            stBeep[u8Chn].fgBeepEn = 0;
            stBeep[u8Chn].u8SoundType = 0;
        }
    }
}



void HalBeepTickTask(uint8 u8Chn)
{
    
    if (1 == stBeep[u8Chn].fgBeepEn)
    {    
        if (0 != stBeep[u8Chn].stSoundBuz.u16Freq)           
        {
            ///<设置蜂鸣器的输出频率
            if(0 == stBeep[u8Chn].fgBeepFreqStart)
            {
                stBeep[u8Chn].fgBeepFreqStart = 1;
                stBeep[u8Chn].BeepPwmStart(u8Chn, stBeep[u8Chn].stSoundBuz.u16Freq);
            }
        } 
        else
        {
            if(0 != stBeep[u8Chn].stSoundBuz.u16Freq)
            {
                stBeep[u8Chn].fgBeepFreqStart = 0;
                stBeep[u8Chn].BeepPwmStop(u8Chn);
                stBeep[u8Chn].BeepFreqPortSet(u8Chn, U8_PIN_LOW);
            }
        }
        
        if(stBeep[u8Chn].stSoundBuz.u16BuzOnTime > 0)
        {
            ///<Buz2输出高电平时间
            stBeep[u8Chn].BeepTimePortSet(u8Chn, U8_PIN_HIGH);
            stBeep[u8Chn].stSoundBuz.u16BuzOnTime--;
        }
        else if(stBeep[u8Chn].stSoundBuz.u16BuzOffTime > 0)
        {
            ///<Buz2输出低电平时间
            stBeep[u8Chn].BeepTimePortSet(u8Chn, U8_PIN_LOW);
            stBeep[u8Chn].stSoundBuz.u16BuzOffTime--;
        }
        else
        {
            if(stBeep[u8Chn].u8Index < U8_MAX_BUZZER_TIMES)
            {
                stBeep[u8Chn].u8Index++;
                HalBeepParaSet(u8Chn, stBeep[u8Chn].u8Index);
            }
        }                    
        
    }
    else
    {
        stBeep[u8Chn].BeepTimePortSet(u8Chn, U8_PIN_LOW);
        stBeep[u8Chn].BeepPwmStop(u8Chn);
        stBeep[u8Chn].BeepFreqPortSet(u8Chn, U8_PIN_LOW);
    }
           
}


void HalBeepSoundSelect(uint8 u8Chn, uint8 u8SoundType)
{
    if(u8Chn < U8_HAL_BEEP_NUM)
    {
        stBeep[u8Chn].u8BuzzerMusicSet = u8SoundType;
    }
}

void HalBeepDisableSet(uint8 u8Chn, uint8 u8Set)
{
    if(u8Chn < U8_HAL_BEEP_NUM)
    {
        stBeep[u8Chn].fgBeepDisable = u8Set;
    }
}

void HalBeepProc(void)
{
    uint8 i;

    for(i = 0; i < U8_HAL_BEEP_NUM; i++)
    {
        ///<禁止蜂鸣器声音
        if(0 != stBeep[i].fgBeepDisable)
        {
            stBeep[i].u8BuzzerMusicSet = 0;
        }
        
        if(stBeep[i].u8BuzzerMusicSet != 0)
        {
             HalBeepSoundOn(i, stBeep[i].u8BuzzerMusicSet);
             HalBeepParaSet(i, stBeep[i].u8Index);
             stBeep[i].u8BuzzerMusicSet = 0;
        }

        if(0 != GetTimeBase4ms())
        {
            HalBeepTickTask(i);
        }

    }
   
}


void HalBeepStartPwm(uint8 u8Chn, uint16 u16Freq)
{
    uint16 u16BuzFreq;
    
    if(U8_HAL_BEEP_CH == u8Chn)
    {
        
        /* Enable writing to registers related to operating modes, LPC, CGC, software reset and LVD */
        SYSTEM.PRCR.WORD = 0xA502;                          /* enable write protection */
        MSTP_MTU1 = 0;                                       /* the module stop state is canceled */

        SYSTEM.PRCR.WORD = 0xA500;                          /* disable write protection */
        /* Stop MTU channel 1 counter */
        MTU.TSTRA.BIT.CST1 = 0U;
        MTU.TSYRA.BIT.SYNC1 = 0U;

        MTU1.TCR.BYTE = 0x00U|0x40U;
        MTU1.TCR2.BYTE = 0x00U;

        MTU1.TIER.BYTE = 0x00U | 0x00U | 0x00U | 0x00U;
        MTU1.TMDR1.BYTE = 0x03U;//PWM2
        MTU1.TIOR.BYTE = 0x03 | 0x00;
        
        /* Enable writing to MPC pin function control registers */
        MPC.PWPR.BIT.B0WI = 0U;
        MPC.PWPR.BIT.PFSWE = 1U;

        /* Set MTIOC1A pin */
        MPC.PA2PFS.BYTE = 0x01U;
        PORTA.PMR.BYTE |= 0x04U;

        /* Disable writing to MPC pin function control registers */
        MPC.PWPR.BIT.PFSWE = 0U;
        MPC.PWPR.BIT.B0WI = 1U;
        
        u16BuzFreq = 32*u16Freq;
        MTU1.TGRA = (u16BuzFreq-1)>>1;
        MTU1.TGRB = u16BuzFreq-1;
        
        /* Start MTU channel 1 counter */
        MTU.TSTRA.BIT.CST1 = 1U;


    }
    else
    {
        ;
    }
    
}

void HalBeepStopPwm(uint8 u8Chn)
{
    if(U8_HAL_BEEP_CH == u8Chn)
    {
        /* Stop MTU channel 1 counter */
        MTU.TSTRA.BIT.CST1 = 0U;
   
        MTU1.TIOR.BYTE = 0x00;

        /* Enable writing to MPC pin function control registers */
        MPC.PWPR.BIT.B0WI = 0U;
        MPC.PWPR.BIT.PFSWE = 1U;
        MPC.PA2PFS.BYTE = 0x00U;
        PORTA.PMR.BYTE &= ~0x04U;
        PORTA.PDR.BIT.B2 = 1;
        PORTA.ODR0.BYTE = _00_Pm2_CMOS_OUTPUT;
        PORTA.PODR.BIT.B2 = 0;

        /* Disable writing to MPC pin function control registers */
        MPC.PWPR.BIT.PFSWE = 0U;
        MPC.PWPR.BIT.B0WI = 1U;
        
                
    }
    else
    {
        ;
    }
    
}

void HalBeepTimePortSet(uint8 u8Chn, uint8 u8Tmp)
{
    if(U8_HAL_BEEP_CH == u8Chn)
    {
        if(U8_PIN_LOW == u8Tmp)
        {
            CLR_PD4;
            SET_PD4_OUTPUT;
        }
        else
        {
            SET_PD4;
            SET_PD4_OUTPUT;
        }
    }
    else
    {
        ;
    }
    
}

void HalBeepFreqPortSet(uint8 u8Chn, uint8 u8Tmp)
{
    if(U8_HAL_BEEP_CH == u8Chn)
    {
        /* Set TO07 pin */
       
        if(U8_PIN_LOW == u8Tmp)
        {
            //CLR_PA2;
            //SET_PA2_OUTPUT;
        }
        else
        {
            //SET_PA2;
            //SET_PA2_OUTPUT;
        }
    }
    else
    {
        ;
    }
    
}

void HalBeepDevInit(void)
{
    stBeep[0].BeepPwmStart = HalBeepStartPwm;
    stBeep[0].BeepPwmStop = HalBeepStopPwm;
    stBeep[0].BeepFreqPortSet = HalBeepFreqPortSet;
    stBeep[0].BeepTimePortSet = HalBeepTimePortSet;
}

void HalBeepTimerHardInit(void)
{
    /* Enable writing to registers related to operating modes, LPC, CGC, software reset and LVD */
    SYSTEM.PRCR.WORD = 0xA502;                          /* enable write protection */
    MSTP_MTU1 = 0;                                       /* the module stop state is canceled */
    SYSTEM.PRCR.WORD = 0xA500;                          /* disable write protection */
    /* Stop MTU channel 1 counter */
    MTU.TSTRA.BIT.CST1 = 0U;
    MTU.TSYRA.BIT.SYNC1 = 0U;
    
    MTU1.TCR.BYTE = 0x00U|0x40U;
    MTU1.TCR2.BYTE = 0x00U;
    MTU1.TIER.BYTE = 0x00U | 0x00U | 0x00U | 0x00U;
   
    MTU1.TMDR1.BYTE = 0x03U;//PWM2
    MTU1.TIOR.BYTE = 0x03 | 0x00;
    
    MTU1.TGRA = 2000;
    MTU1.TGRB = 4000;
   
    /* Enable writing to MPC pin function control registers */
    MPC.PWPR.BIT.B0WI = 0U;
    MPC.PWPR.BIT.PFSWE = 1U;
   
    /* Set MTIOC1A pin */
    MPC.PA2PFS.BYTE = 0x01U;
    PORTA.PMR.BYTE |= 0x04U;

     /* Disable writing to MPC pin function control registers */
     MPC.PWPR.BIT.PFSWE = 0U;
     MPC.PWPR.BIT.B0WI = 1U;

    /* Enable protection */
    SYSTEM.PRCR.WORD = 0xA500U;
}

void HalBeepInit(void)
{
    HalBeepTimerHardInit();
    HalBeepSoundSelect(U8_HAL_BEEP_CH, U8_POWER_UP_SOUND);///<首次上电，赋值为上电蜂鸣器声音
    HalBeepDevInit();
    SET_PD6_OUTPUT;
    SET_PD6;
}
///<单音蜂鸣器
#elif((U8_HAL_COMMON_BEEP_EN == 1)&&(U8_HAL_BEEP_NUM > 0))

void HalBeepStartPwm(uint8 u8Chn, uint16 u16BuzCycle);
void HalBeepStopPwm(uint8 u8Chn);


typedef struct
{   
  uint8  u8BuzStage;
  uint8  u8BuzzerSoundSet;
  uint8  u8BuzzerSoundCnt;
  uint16 u16BuzzCtrlTim; 	//开启时间,单位为500us
  uint16 u16BuzzCtrlTimTick; 	//开启时间,单位为500us
  uint8  u8BeepDisable;
  
  void (*BeepPwmStop)(uint8 u8Chn);
  void (*BeepPwmStart)(uint8 u8Chn, uint16 u16BuzCycle);
}stBeepType;

stBeepType stBeep[U8_HAL_BEEP_NUM];


///<蜂鸣器声音设置
///<1:表示响一声， 2：表示响两声，3：表示响三声
void HalBeepSoundSet(uint8 u8Chn, uint8 u8Sound, uint16 u16SoundTim_4ms)
{
    if(u8Chn < U8_HAL_BEEP_NUM)
    {
        stBeep[u8Chn].u8BuzzerSoundSet = u8Sound;
        stBeep[u8Chn].u16BuzzCtrlTim = u16SoundTim_4ms;
    }
}

void HalBeepDisableSet(uint8 u8Chn, uint8 u8Set)
{
    if(u8Chn < U8_HAL_BEEP_NUM)
    {
        stBeep[u8Chn].u8BeepDisable = u8Set;
    }
}


void HalBeepProc(void)
{
    uint8 i;
    for(i = 0; i < U8_HAL_BEEP_NUM; i++)
    {
        if(1 == GetTimeBase4ms())
        {
            if(stBeep[i].u16BuzzCtrlTimTick > 0)
            {
                stBeep[i].u16BuzzCtrlTimTick--;
            }
        }

        ///<关闭蜂鸣器声音
        if(stBeep[i].u8BeepDisable == 1)
        {
            stBeep[i].u8BuzzerSoundSet = 0;
            stBeep[i].u8BuzStage = 0; 
        }
        
        ///<有蜂鸣器声音需求
        if(stBeep[i].u8BuzzerSoundSet > 0)
        {
            if(0 == stBeep[i].u8BuzzerSoundCnt)
            {
                stBeep[i].u8BuzzerSoundCnt = stBeep[i].u8BuzzerSoundSet;
                stBeep[i].u8BuzzerSoundSet = 0;
                stBeep[i].u8BuzStage = 1;         
            }
        }
            
        switch (stBeep[i].u8BuzStage)
        {
            case 1:
            {///<设定蜂鸣器频率，蜂鸣器声音时间为300ms
                
                stBeep[i].BeepPwmStart(i, U16_BEEP_CYCLE_SET);///<XM蜂鸣器声音的频率为8Khz
                stBeep[i].u16BuzzCtrlTimTick = stBeep[i].u16BuzzCtrlTim;///<响一声的时间长度
                stBeep[i].u8BuzStage = 2;
            }break;

            case 2:
            {
                ///<等待蜂鸣器声响结束
                if(0 == stBeep[i].u16BuzzCtrlTimTick)
                {
                    stBeep[i].u8BuzStage = 3;
                }
                
            }break;

            case 3:
            {///<关闭蜂鸣器声音
                
                stBeep[i].BeepPwmStop(0);

                if(stBeep[i].u8BuzzerSoundCnt > 0)
                {
                    stBeep[i].u8BuzzerSoundCnt--;
                }
                
                if(stBeep[i].u8BuzzerSoundCnt == 0)
                {
                    stBeep[i].u8BuzzerSoundSet = 0;
                    stBeep[i].u8BuzStage = 0;   ///<已结束当前声响
                }
                else
                {///<下一次蜂鸣器声响
                    stBeep[i].u8BuzStage = 4;
                    stBeep[i].u16BuzzCtrlTimTick = stBeep[i].u16BuzzCtrlTim;///<响一声的时间长度
                }
                
            }break;
            
            case 4:
            {///<间隔第二声响的延时等待时间
                if(0 == stBeep[i].u16BuzzCtrlTimTick)
                {
                    stBeep[i].u8BuzStage = 1;
                }
            }break;

            default:
            {
                stBeep[i].u8BuzStage = 0;
                stBeep[i].u8BuzzerSoundCnt = 0;
                stBeep[i].BeepPwmStop(0);
            }
            break;
        }
    }
}


void HalBeepStartPwm(uint8 u8Chn, uint16 u16BuzCycle)
{
    if(U8_HAL_BEEP_CH == u8Chn)
    {

    }
    else
    {

    }
}

void HalBeepStopPwm(uint8 u8Chn)
{
    if(U8_HAL_BEEP_CH == u8Chn)
    {

    }
    else
    {

    }
}

void HalBeepInit(void)
{
    uint8 i;
    for(i = 0; i < U8_HAL_BEEP_NUM; i++)
    {
        stBeep[i].BeepPwmStart = HalBeepStartPwm;
        stBeep[i].BeepPwmStop = HalBeepStartPwm;
    }
}

#endif



